(SST) ShlWAPI.pas Version 1.08

Developer Reference
(SST)ShlWAPI ChrCmpI Function
Compares two single or double byte character set (DBCS) characters, without case sensitivity.
Scope
Global (i.e. this function can be called/accessed from code in any unit that includes/uses (SST)ShlWAPI.pas).
Syntax
function ChrCmpI(w1 : WORD; w2 : WORD) : BOOL;
Parameters
w1 [in] The first of the two characters to compare.
w2 [in] The second of the two characters to compare.
Return Values
The function returns 0 (= FALSE) if the compared characers are identical or represent the upper and lower case version of the same character (e.g. "A" and "a"). The function returns 1 (= TRUE) if the compared characters represent different characters (e.g. "B" and "C").
Remarks
This function (ChrCmpI) is highly unusual in two aspects:
1. Contrary to what one would expect from a function that compares two characters, it does NOT return true if they are the same character, it returns FALSE.
2. Both the ANSI and wide char (i.e. the DBCS) versions of the function require that they are passed two double byte (i.e. WORD) values for comparison, and not as one would expect, two single byte (i.e. CHAR) values in the ANSI version. This necessitates that not only the wide char but also the ANSI version of the function (ChrCmpIA) be called with two WORD values or two character (CHAR) values cast to two WORD values, as in the examples further below.
In both versions of the function (ChrCmpIA and ChrCmpIW) the function checks if the parameters passed to it are double byte (i.e. "wide") characters by calling function IsDBCSLeadByte (which see) prior to performing the actual comparison. This is also the reason why the parameters have to be WORD (i.e. 16 bit) values.
At least in one version of the Microsoft documentation at our disposal, at the time the function was tested and documented by us (Jan. 2024), the Microsoft description was erroneous. Although older versions of the Microsoft documentation contained the correct function prototypes in the description (i.e. "BOOL ChrCmpIA(WORD w1, WORD w2);" and "BOOL ChrCmpIW(WCHAR w1, WCHAR w2);"), in a later description the function is described as having to be called with two TCHAR values, although the function prototypes in the header file of the SDK, are identical to those of the preceding versions (i.e. they are called with two WORD values, both in the ANSI and wide character versions). This is a documntation error in the Microsoft documents in which the function is described as accepting two TCHAR values, because TCHARs resolve to CHAR when not compiled as a Unicode (i.e. wide char) library, application, etc.
Example
PROCEDURE TForm4.TestChrCmpI(Sender : TObject); VAR charstocomp1 : CHAR; VAR charstocomp2 : CHAR; VAR wcharstocomp1 : WideChar; VAR wcharstocomp2 : WideChar; VAR charvalstr : STRING; VAR apiretval : BOOL; VAR newinfoline : STRING; BEGIN charstocomp1 := #0; charstocomp2 := #0; FillChar(wcharstocomp1, SizeOf(wcharstocomp1), #0); FillChar(wcharstocomp2, SizeOf(wcharstocomp2), #0); charvalstr := ''; apiretval := FALSE; newinfoline := ''; charstocomp1 := #9; //Tab charstocomp2 := #13; //Line feed charvalstr := '#' + IntToStr(WORD(charstocomp1)) + ' (0x' + IntToHex(WORD(charstocomp1) , 4) + ')'; charvalstr := charvalstr + ' and #' + IntToStr(WORD(charstocomp2)) + ' (0x' + IntToHex(WORD(charstocomp2) , 4) + ')'; apiretval := ChrCmpIA(WORD(charstocomp1), WORD(charstocomp2)); newinfoline := 'ChrCmpIA called with ' + charvalstr + ' returned : '; IF (apiretval = TRUE) THEN newinfoline := newinfoline + 'TRUE' ELSE newinfoline := newinfoline + 'FALSE'; Memo1.Lines.Add(newinfoline); charstocomp1 := 'A'; charstocomp2 := 'A'; charvalstr := '"' + charstocomp1 + '" (0x' + IntToHex(WORD(charstocomp1) , 4) + ')'; charvalstr := charvalstr + ' and "' + charstocomp2 + '" (0x' + IntToHex(WORD(charstocomp2) , 4) + ')'; apiretval := ChrCmpIA(WORD(charstocomp1), WORD(charstocomp2)); newinfoline := 'ChrCmpIA called with ' + charvalstr + ' returned : '; IF (apiretval = TRUE) THEN newinfoline := newinfoline + 'TRUE' ELSE newinfoline := newinfoline + 'FALSE'; Memo1.Lines.Add(newinfoline); charstocomp1 := 'A'; charstocomp2 := 'z'; charvalstr := '"' + charstocomp1 + '" (0x' + IntToHex(WORD(charstocomp1) , 4) + ')'; charvalstr := charvalstr + ' and "' + charstocomp2 + '" (0x' + IntToHex(WORD(charstocomp2) , 4) + ')'; apiretval := ChrCmpIA(WORD(charstocomp1), WORD(charstocomp2)); newinfoline := 'ChrCmpIA called with ' + charvalstr + ' returned : '; IF (apiretval = TRUE) THEN newinfoline := newinfoline + 'TRUE' ELSE newinfoline := newinfoline + 'FALSE'; Memo1.Lines.Add(newinfoline); charstocomp1 := 'A'; charstocomp2 := 'a'; charvalstr := '"' + charstocomp1 + '" (0x' + IntToHex(WORD(charstocomp1) , 4) + ')'; charvalstr := charvalstr + ' and "' + charstocomp2 + '" (0x' + IntToHex(WORD(charstocomp2) , 4) + ')'; apiretval := ChrCmpIA(WORD(charstocomp1), WORD(charstocomp2)); newinfoline := 'ChrCmpIA called with ' + charvalstr + ' returned : '; IF (apiretval = TRUE) THEN newinfoline := newinfoline + 'TRUE' ELSE newinfoline := newinfoline + 'FALSE'; Memo1.Lines.Add(newinfoline); wcharstocomp1 := #9;//Tab wcharstocomp2 := #13; //Line feed charvalstr := '#' + IntToStr(WORD(wcharstocomp1)) + ' (0x' + IntToHex(WORD(wcharstocomp1) , 4) + ')'; charvalstr := charvalstr + ' and #' + IntToStr(WORD(wcharstocomp2)) + ' (0x' + IntToHex(WORD(wcharstocomp2) , 4) + ')'; apiretval := ChrCmpIW(WORD(wcharstocomp1), WORD(wcharstocomp2)); newinfoline := 'ChrCmpIW called with ' + charvalstr + ' returned : '; IF (apiretval = TRUE) THEN newinfoline := newinfoline + 'TRUE' ELSE newinfoline := newinfoline + 'FALSE'; Memo1.Lines.Add(newinfoline); wcharstocomp1 := 'B'; wcharstocomp2 := 'B'; charstocomp1 := 'B'; charstocomp2 := 'B'; charvalstr := '"' + charstocomp1 + '" (0x' + IntToHex(WORD(wcharstocomp1) , 4) + ')'; charvalstr := charvalstr + ' and "' + charstocomp2 + '" (0x' + IntToHex(WORD(wcharstocomp2) , 4) + ')'; apiretval := ChrCmpIW(WORD(wcharstocomp1), WORD(wcharstocomp2)); newinfoline := 'ChrCmpIW called with ' + charvalstr + ' returned : '; IF (apiretval = TRUE) THEN newinfoline := newinfoline + 'TRUE' ELSE newinfoline := newinfoline + 'FALSE'; Memo1.Lines.Add(newinfoline); wcharstocomp1 := 'a'; wcharstocomp2 := 'Z'; charstocomp1 := 'a'; charstocomp2 := 'Z'; charvalstr := '"' + charstocomp1 + '" (0x' + IntToHex(WORD(wcharstocomp1) , 4) + ')'; charvalstr := charvalstr + ' and "' + charstocomp2 + '" (0x' + IntToHex(WORD(wcharstocomp2) , 4) + ')'; apiretval := ChrCmpIW(WORD(wcharstocomp1), WORD(wcharstocomp2)); newinfoline := 'ChrCmpIW called with ' + charvalstr + ' returned : '; IF (apiretval = TRUE) THEN newinfoline := newinfoline + 'TRUE' ELSE newinfoline := newinfoline + 'FALSE'; Memo1.Lines.Add(newinfoline); wcharstocomp1 := #915; //Upper case, Greek gamma symbol wcharstocomp2 := #915; //Upper case, Greek gamma symbol charvalstr := 'upper case symbol for gamma ' + ' (0x' + IntToHex(WORD(wcharstocomp1) , 4) + ')'; charvalstr := charvalstr + ' and upper case symbol for gamma '+ ' (0x' + IntToHex(WORD(wcharstocomp2) , 4) + ')'; apiretval := ChrCmpIW(WORD(wcharstocomp1), WORD(wcharstocomp2)); newinfoline := 'ChrCmpIW called with ' + charvalstr + ' returned : '; IF (apiretval = TRUE) THEN newinfoline := newinfoline + 'TRUE' ELSE newinfoline := newinfoline + 'FALSE'; Memo1.Lines.Add(newinfoline); wcharstocomp1 := #960; //Lower case, Greek pi symbol wcharstocomp2 := #928; //Upper case, Greek pi symbol charvalstr := 'Lower case symbol for pi ' + ' (0x' + IntToHex(WORD(wcharstocomp1) , 4) + ')'; charvalstr := charvalstr + ' and upper case symbol for pi '+ ' (0x' + IntToHex(WORD(wcharstocomp2) , 4) + ')'; apiretval := ChrCmpIW(WORD(wcharstocomp1), WORD(wcharstocomp2)); newinfoline := 'ChrCmpIW called with ' + charvalstr + ' returned : '; IF (apiretval = TRUE) THEN newinfoline := newinfoline + 'TRUE' ELSE newinfoline := newinfoline + 'FALSE'; Memo1.Lines.Add(newinfoline); wcharstocomp1 := #916; //Upper case, Greek delta symbol wcharstocomp2 := #952; //Upper case, Greek theta symbol charvalstr := 'upper case symbol for delta ' + ' (0x' + IntToHex(WORD(wcharstocomp1) , 4) + ')'; charvalstr := charvalstr + ' and upper case symbol for theta '+ ' (0x' + IntToHex(WORD(wcharstocomp2) , 4) + ')'; apiretval := ChrCmpIW(WORD(wcharstocomp1), WORD(wcharstocomp2)); newinfoline := 'ChrCmpIW called with ' + charvalstr + ' returned : '; IF (apiretval = TRUE) THEN newinfoline := newinfoline + 'TRUE' ELSE newinfoline := newinfoline + 'FALSE'; Memo1.Lines.Add(newinfoline); newinfoline := ''; Memo1.Lines.Add(newinfoline); END;
Under Windows 10, the above example produced the following output:
ChrCmpIA called with #9 (0x0009) and #13 (0x000D) returned : TRUE ChrCmpIA called with "A" (0x0041) and "A" (0x0041) returned : FALSE ChrCmpIA called with "A" (0x0041) and "z" (0x007A) returned : TRUE ChrCmpIA called with "A" (0x0041) and "a" (0x0061) returned : FALSE ChrCmpIW called with #9 (0x0009) and #13 (0x000D) returned : TRUE ChrCmpIW called with "B" (0x0042) and "B" (0x0042) returned : FALSE ChrCmpIW called with "a" (0x0061) and "Z" (0x005A) returned : TRUE ChrCmpIW called with upper case symbol for gamma (0x0393) and upper case symbol for gamma (0x0393) returned : FALSE ChrCmpIW called with Lower case symbol for pi (0x03C0) and upper case symbol for pi (0x03A0) returned : FALSE ChrCmpIW called with upper case symbol for delta (0x0394) and upper case symbol for theta (0x03B8) returned : TRUE
Requirements
Unit: Declared and imported in (SST)ShlWAPI.pas
Library: (SST)ShlWAPI.dcu/(SST)ShlWAPI.obj
Unicode: Implemented as ANSI (ChrCmpI and ChrCmpIA) and Unicode (ChrCmpIW) functions.
Min. ShlWAPI.dll version according to MS SDK doc.: 4.71
Min. ShlWAPI.dll version based on SST research: 4.71
Min. OS version(s) according to Microsoft SDK doc.: Windows NT 4.0 with IE 4.0, Windows 95 with IE 4.0, Windows 98, Windows 2000
Min. OS version(s) according to SST research.: Windows NT 4.0 with IE 4.0, Windows 95 with IE 4.0, Windows 98, Windows 2000
See Also
IsCharSpace.
 
Windows APIs: StrChr, IsCharSpace


Document/Contents version 1.00
Page/URI last updated on 26.01.2024
 
Copyright © Stoelzel Software Technologie (SST) 2024
Suggestions and comments mail to:
webmaster@stoelzelsoftwaretech.com